package com.kangyi.admin.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.kangyi.admin.mapper.AdminUserMapper;
import com.kangyi.admin.mapper.PublicActivityImageMapper;
import com.kangyi.admin.mapper.PublicActivityMapper;
import com.kangyi.admin.service.AdminUserService;
import com.kangyi.constant.MessageConstant;
import com.kangyi.constant.PasswordConstant;
import com.kangyi.context.BaseContext;
import com.kangyi.dto.*;
import com.kangyi.entity.AdminUser;
import com.kangyi.exception.*;
import com.kangyi.result.PageResult;
import com.kangyi.vo.AdminUserVO;
import com.kangyi.vo.ManageAccountPageQueryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDate;
import java.time.Period;
import java.util.List;

/**
 * @author Blank
 * @version 1.0
 */
@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private PublicActivityMapper publicActivityMapper;



    //调用后检查当前线程id是否有足够的权限进行后续操作
    public void validateUserPermissions() {
        Integer currentId = BaseContext.getCurrentId();
        AdminUserVO adminUserVO = adminUserMapper.selectById(currentId);
        if (!adminUserVO.getPermissions().equals(1)) {
            throw new PermissionsException(MessageConstant.INSUFFICIENT_PRIVILEGE);
        }
    }

    @Override
    public AdminUser login(AdminUserLoginDTO adminUserLoginDTO) {
        String phone = adminUserLoginDTO.getPhone();
        String password = adminUserLoginDTO.getPassword();

        AdminUser adminUser = adminUserMapper.getAdminUser(null,phone);
        if (adminUser == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(adminUser.getPassword())) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }
        return adminUser;
    }


    @Override
    public void update(AdminUserEditDTO adminUserEditDTO) {
        AdminUser adminUser = AdminUser.builder()
                .id(adminUserEditDTO.getId())
                .age(adminUserEditDTO.getAge())
                .gender(adminUserEditDTO.getGender())
                .headshot(adminUserEditDTO.getHeadshot())
                .name(adminUserEditDTO.getName())
                .build();
        adminUserMapper.update(adminUser);
    }

    @Override
    public void updateByPassword(PasswordEditDTO passwordEditDTO) {

        if (passwordEditDTO.getOldPassword().equals(passwordEditDTO.getNewPassword())) {
            throw new PasswordErrorException(MessageConstant.NEW_PASSWORD_ERROR);
        }

        passwordEditDTO.setOldPassword(DigestUtils.md5DigestAsHex(passwordEditDTO.getOldPassword().getBytes()));
        passwordEditDTO.setNewPassword(DigestUtils.md5DigestAsHex(passwordEditDTO.getNewPassword().getBytes()));

        AdminUser adminUser = adminUserMapper.getAdminUsersById(passwordEditDTO.getId());

        if (!adminUser.getPassword().equals(passwordEditDTO.getOldPassword())) {
            throw new PasswordErrorException(MessageConstant.OLD_PASSWORD_ERROR);
        }

        adminUserMapper.updateByPassword(passwordEditDTO);
    }



    @Override
    public void forgotPassword(ForgotPasswordDTO forgotPasswordDTO) {

        AdminUser adminUser = adminUserMapper.getAdminUser(null, forgotPasswordDTO.getPhone());
        if (adminUser == null) {
            throw new AccountException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        forgotPasswordDTO.setNewPassword(DigestUtils.md5DigestAsHex(forgotPasswordDTO.getNewPassword().getBytes()));

        adminUserMapper.forgotPassword(forgotPasswordDTO);
    }

    @Override
    public void changePhone(ChangePhoneDTO changePhoneDTO) {

        adminUserMapper.updateByPhone(changePhoneDTO);

    }

    @Override
    public AdminUserVO inquiryAdminUser() {
        Integer currentId = BaseContext.getCurrentId();

        if (currentId == null) {
            throw new DataNotExistException(MessageConstant.TOKEN_IS_NOT_EXIST);
        }

        return adminUserMapper.selectById(currentId);
    }

    @Override
    public PageResult manageAccountPageQuery(ManageAccountPageQueryDTO manageAccountPageQueryDTO) {
        validateUserPermissions();
        PageHelper.startPage(manageAccountPageQueryDTO.getPage(),manageAccountPageQueryDTO.getPageSize());
        Page<ManageAccountPageQueryVO> page = adminUserMapper.pageQuery(manageAccountPageQueryDTO);
        long total = page.getTotal();
        List<ManageAccountPageQueryVO> result = page.getResult();
        return new PageResult(total,result);
    }

    @Override
    @Transactional
    public void deleteManageAccount(List<Integer> ids) {
        validateUserPermissions();
        Integer currentId = BaseContext.getCurrentId();
        if (!currentId.equals(1)){
            throw new AccountException(MessageConstant.NO_PERMISSION_OPERATION);
        }
        for (Integer id : ids) {
            if (id.equals(1)) {
                throw new AccountException(MessageConstant.UNABLE_TO_OPERATE_SUPER_ADMINISTRATOR_ACCOUNT);
            }
            publicActivityMapper.updateByUserId(id);
            adminUserMapper.deleteById(id);
        }
    }

    @Override
    public void bulkOperation(BulkOperationDTO bulkOperationDTO) {
        validateUserPermissions();
        Integer currentId = BaseContext.getCurrentId();
        if (!currentId.equals(1)){
            throw new AccountException(MessageConstant.NO_PERMISSION_OPERATION);
        }
        for (Integer id : bulkOperationDTO.getIds()) {
            if (id.equals(1)) {
                throw new AccountException(MessageConstant.UNABLE_TO_OPERATE_SUPER_ADMINISTRATOR_ACCOUNT);
            }
            AdminUser build = AdminUser.builder()
                    .id(id)
                    .status(bulkOperationDTO.getType())
                    .build();
            adminUserMapper.bulkOperation(build);
        }
    }

    @Override
    public void addManageAccount(AddManageAccountDTO addManageAccountDTO) {
        validateUserPermissions();
        genderFromIDCard(addManageAccountDTO.getIdCard());
        calculateAgeFromIDCard(addManageAccountDTO.getIdCard());
        AdminUser adminUser = AdminUser.builder()
                .name(addManageAccountDTO.getName())
                .phone(addManageAccountDTO.getPhone())
                .idCard(addManageAccountDTO.getIdCard())
                .password(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()))
                .status(AdminUser.ENABLED)
                .permissions(AdminUser.SUPER_ADMINISTRATOR)
                .position(AdminUser.SUPER_ADMINISTRATORS)
                .gender(genderFromIDCard(addManageAccountDTO.getIdCard()))
                .age(calculateAgeFromIDCard(addManageAccountDTO.getIdCard()))
                .build();

        adminUserMapper.addAdminUser(adminUser);
    }

    public Integer genderFromIDCard(String idCard){
        // 检查身份证号码长度是否合法
        if (idCard.length() != 15 && idCard.length() != 18) {
            throw new DataNotExistException(MessageConstant.ILLEGAL_ID_CARD);
        }
        int genderDigit;
        // 对于 15 位身份证号码，第 15 位代表性别
        if (idCard.length() == 15) {
            genderDigit = Integer.parseInt(idCard.substring(14, 15));
        }
        // 对于 18 位身份证号码，第 17 位代表性别
        else {
            genderDigit = Integer.parseInt(idCard.substring(16, 17));
        }
        // 判断性别
        if (genderDigit % 2 == 1) {
            return 1;
        } else {
            return 0;
        }
    }

    public String calculateAgeFromIDCard(String idCard){
        // 检查身份证号码长度是否合法
        if (idCard.length() != 15 && idCard.length() != 18) {
            throw new IllegalArgumentException("无效的身份证号码");
        }
        int birthYear, birthMonth, birthDay;
        // 对于 15 位身份证号码，年份需要补全
        if (idCard.length() == 15) {
            birthYear = 1900 + Integer.parseInt(idCard.substring(6, 8));
            birthMonth = Integer.parseInt(idCard.substring(8, 10));
            birthDay = Integer.parseInt(idCard.substring(10, 12));
        }
        // 对于 18 位身份证号码
        else {
            birthYear = Integer.parseInt(idCard.substring(6, 10));
            birthMonth = Integer.parseInt(idCard.substring(10, 12));
            birthDay = Integer.parseInt(idCard.substring(12, 14));
        }
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 构建出生日期
        LocalDate birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
        // 计算年龄
        Period period = Period.between(birthDate, currentDate);

        return String.valueOf(period.getYears());
    }
}
